package cn.starrysky108.simpleerp.core.util;

import cn.starrysky108.simpleerp.core.base.BaseResponseEntity;
import cn.starrysky108.simpleerp.core.util.entity.IpInfo;
import lombok.Synchronized;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Future;

/**
 * @author Carl Lee
 */
@Slf4j
@Component
public class HttpUtil {

    private static String port = "8080";
    private static String host = "127.0.0.1";

    /**
     * 获取客户端ip地址
     *
     * @return ip
     */
    public static String getClientIp(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        String unknown = "unknown";
        if (!StringUtils.hasText(ip) || unknown.equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (!StringUtils.hasText(ip) || unknown.equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (!StringUtils.hasText(ip) || unknown.equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        // 多个路由时，取第一个非unknown的ip
        final String[] arr = ip.split(",");
        for (final String str : arr) {
            if (!"unknown".equalsIgnoreCase(str)) {
                ip = str;
                break;
            }
        }
        return ip;
    }

    @Synchronized
    public static IpInfo getIpInfo(String ip) {
        String url = "https://ip.taobao.com/outGetIpInfo";
        Map<String, String> data = new HashMap<>(2);
        data.put("ip", ip);
        data.put("accessKey", "alibaba-inc");
        return HttpUtil.get(url, IpInfo.class, data);
    }

    /**
     * 进行普通get请求
     *
     * @param url url地址
     * @return 请求结果
     */
    public static String get(String url) {
        RestTemplate restTemplate = new RestTemplate();
        return restTemplate.getForObject(url, String.class);
    }

    /**
     * 进行普通get请求
     *
     * @param url        url地址
     * @param returnType 返回结果类型
     * @param data       请求参数
     * @return 请求结果，自动封装为T对象
     */
    public static <T> T get(String url, Class<T> returnType, Map<String, ?> data) {
        RestTemplate restTemplate = new RestTemplate();
        return restTemplate.getForObject(url, returnType, data);
    }

    /**
     * post请求
     *
     * @param url        url地址
     * @param returnType 返回结果类型
     * @param data       请求参数
     * @return 请求结果，自动封装为T对象
     */

    public static <T> T post(String url, Class<T> returnType, Map<String, String> data) {
        RestTemplate restTemplate = new RestTemplate();
        return restTemplate.postForObject(url, null, returnType, data);
    }

    /**
     * 响应简单json数据到浏览器
     *
     * @param entity 数据信息
     */
    public static void customResponse(BaseResponseEntity<?> entity, ServletResponse response) {
        String data = CastUtil.objToJson(entity);
        response.setContentType("application/json; charset=utf-8");
        response.setCharacterEncoding("UTF-8");
        try (OutputStream outputStream = response.getOutputStream()) {
            assert data != null;
            outputStream.write(data.getBytes(StandardCharsets.UTF_8));
            outputStream.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Async
    public Future<String> test() throws InterruptedException {
        Thread.sleep(8000);
        return AsyncResult.forValue("完成执行");
    }

    @Async
    public void test1() throws InterruptedException {
        Thread.sleep(8000);
    }

    public static String getServerUrl() {
        return String.format("http://%s:%s/", host, port);
    }

}
